<?php
if (!defined('BASEPATH'))
	exit ('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package		CodeIgniter
 * @author		ExpressionEngine Dev Team
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
 * @license		http://codeigniter.com/user_guide/license.html
 * @link		http://codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * CodeIgniter Calendar Class
 *
 * This class enables the creation of calendars
 *
 * @package		CodeIgniter
 * @subpackage	Libraries
 * @category	Libraries
 * @author		ExpressionEngine Dev Team
 * @link		http://codeigniter.com/user_guide/libraries/calendar.html
 */
class CI_Calendar {

	var $CI;
	var $lang;
	var $local_time;
	var $template = '';
	var $start_day = 'sunday';
	var $month_type = 'long';
	var $day_type = 'abr';
	var $show_next_prev = FALSE;
	var $next_prev_url = '';

	/**
	 * Constructor
	 *
	 * Loads the calendar language file and sets the default time reference
	 */
	public function __construct($config = array ()) {
		$this->CI = & get_instance();

		if (!in_array('calendar_lang.php', $this->CI->lang->is_loaded, TRUE)) {
			$this->CI->lang->load('calendar');
		}

		$this->local_time = time();

		if (count($config) > 0) {
			$this->initialize($config);
		}

		log_message('debug', "Calendar Class Initialized");
	}

	// --------------------------------------------------------------------

	/**
	 * Initialize the user preferences
	 *
	 * Accepts an associative array as input, containing display preferences
	 *
	 * @access	public
	 * @param	array	config preferences
	 * @return	void
	 */
	function initialize($config = array ()) {
		foreach ($config as $key => $val) {
			if (isset ($this-> $key)) {
				$this-> $key = $val;
			}
		}
	}

	// --------------------------------------------------------------------

	/**
	 * Generate the calendar
	 *
	 * @access	public
	 * @param	integer	the year
	 * @param	integer	the month
	 * @param	array	the data to be shown in the calendar cells
	 * @return	string
	 */
	function generate($year = '', $month = '', $data = array ()) {
		// Set and validate the supplied month/year
		if ($year == '')
			$year = date("Y", $this->local_time);

		if ($month == '')
			$month = date("m", $this->local_time);

		if (strlen($year) == 1)
			$year = '200' . $year;

		if (strlen($year) == 2)
			$year = '20' . $year;

		if (strlen($month) == 1)
			$month = '0' . $month;

		$adjusted_date = $this->adjust_date($month, $year);

		$month = $adjusted_date['month'];
		$year = $adjusted_date['year'];

		// Determine the total days in the month
		$total_days = $this->get_total_days($month, $year);

		// Set the starting day of the week
		$start_days = array (
			'sunday' => 0,
			'monday' => 1,
			'tuesday' => 2,
			'wednesday' => 3,
			'thursday' => 4,
			'friday' => 5,
			'saturday' => 6
		);
		$start_day = (!isset ($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day];

		// Set the starting day number
		$local_date = mktime(12, 0, 0, $month, 1, $year);
		$date = getdate($local_date);
		$day = $start_day +1 - $date["wday"];

		while ($day > 1) {
			$day -= 7;
		}

		// Set the current month/year/day
		// We use this to determine the "today" date
		$cur_year = date("Y", $this->local_time);
		$cur_month = date("m", $this->local_time);
		$cur_day = date("j", $this->local_time);

		$is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE;

		// Generate the template data array
		$this->parse_template();

		// Begin building the calendar output
		$out = $this->temp['table_open'];
		$out .= "\n";

		$out .= "\n";
		$out .= $this->temp['heading_row_start'];
		$out .= "\n";

		// "previous" month link
		if ($this->show_next_prev == TRUE) {
			// Add a trailing slash to the  URL if needed
			$this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/", $this->next_prev_url);

			$adjusted_date = $this->adjust_date($month -1, $year);
			$out .= str_replace('{previous_url}', $this->next_prev_url . $adjusted_date['year'] . '/' . $adjusted_date['month'], $this->temp['heading_previous_cell']);
			$out .= "\n";
		}

		// Heading containing the month/year
		$colspan = ($this->show_next_prev == TRUE) ? 5 : 7;
		$this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']);
		$selected="";$selected1="";$selected2="";$selected3="";
		$s1="";$s2="";$s3="";$s4="";$s5="";$s6="";$s7="";$s8="";$s9="";$s10="";$s11="";$s12="";
		if($year == 2012){
			$selected="selected='selected'";
		}
		if($year == 2013){
			$selected1="selected='selected'";
		}
		if($year == 2014){
			$selected2="selected='selected'";
		}
		if($year == 2015){
			$selected3="selected='selected'";
		}
		switch ($month) {
			case '01' :
				$s1="selected='selected'";
				break;
			case '02' :
				$s2="selected='selected'";
				break;
			case '03' :
				$s3="selected='selected'";
				break;
			case '04' :
				$s4="selected='selected'";
				break;
			case '05' :
				$s5="selected='selected'";
				break;
			case '06' :
				$s6="selected='selected'";
				break;
			case '07' :
				$s7="selected='selected'";
				break;
			case '08' :
				$s8="selected='selected'";
				break;
			case '09' :
				$s9="selected='selected'";
				break;
			case 10 :
				$s10="selected='selected'";
				break;
			case 11 :
				$s11="selected='selected'";
				break;
			case 12 :
				$s12="selected='selected'";
				break;
		}
		$head_string = '<b>
			<select onchange="javascript:editaction_argv_year=this.value;editaction_load();" id="year" name="year" size="1" style="font-size:14px;margin:8px 0 0 0;background:#E8EEF7; border:1px solid #ccc;">
		       <option '.$selected.' value="2012">2012</option><option '.$selected1.' value="2013">2013</option><option '.$selected2.' value="2014" >2014</option><option '.$selected3.' value="2015">2015</option>
		    </select>
              </b>年 <b><select onchange="javascript:editaction_argv_month=this.value;editaction_load2();" id="month" name="month" size="1" style="font-size:14px;margin:8px 0 0 0;background:#E8EEF7; border:1px solid #ccc;">
		       <option '.$s1.' value="01">1</option><option '.$s2.'  value="02">2</option><option '.$s3.'  value="03">3</option><option '.$s4.'  value="04">4</option><option '.$s5.'  value="05">5</option><option '.$s6.'  value="06">6</option><option '.$s7.'  value="07">7</option><option '.$s8.'  value="08">8</option><option '.$s9.'  value="09">9</option><option '.$s10.'  value="10">10</option><option '.$s11.'  value="11">11</option><option '.$s12.'  value="12">12</option>
		    </select> </b>月';

		$this->temp['heading_title_cell'] = str_replace('{heading}', $head_string, $this->temp['heading_title_cell']);
		$out .= $this->temp['heading_title_cell'];
		$out .= "\n";

		// "next" month link
		if ($this->show_next_prev == TRUE) {
			$adjusted_date = $this->adjust_date($month +1, $year);
			$out .= str_replace('{next_url}', $this->next_prev_url . $adjusted_date['year'] . '/' . $adjusted_date['month'], $this->temp['heading_next_cell']);
		}

		$out .= "\n";
		$out .= $this->temp['heading_row_end'];
		$out .= "\n";

		// Write the cells containing the days of the week
		$out .= "\n";
		$out .= $this->temp['week_row_start'];
		$out .= "\n";

		$day_names = $this->get_day_names();
		for ($i = 0; $i < 7; $i++) {
			$out .= str_replace('{week_day}', $day_names[($start_day + $i) % 7], $this->temp['week_day_cell']);
		}

		$out .= "\n";
		$out .= $this->temp['week_row_end'];
		$out .= "\n";
		// Build the main body of the calendar
		while ($day <= $total_days) {
			$out .= "\n";
			$out .= $this->temp['cal_row_start'];
			$out .= "\n";

			for ($i = 0; $i < 7; $i++) {
				$out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];

				if ($day > 0 AND $day <= $total_days) {
					if (isset ($data[$day])) {
						// Cells with content
						$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
						$out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));
					} else {
						// Cells with no content
						$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
						$out .= str_replace('{day}', $day, $temp);
					}
				} else {
					// Blank cells
					$out .= $this->temp['cal_cell_blank'];
				}

				$out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];
				$day++;
			}

			$out .= "\n";
			$out .= $this->temp['cal_row_end'];
			$out .= "\n";
		}

		$out .= "\n";
		$out .= $this->temp['table_close'];

		$out = str_replace('{month}', $month, $out);
		$out = str_replace('{year}', $year, $out);

		return $out;
	}

	// --------------------------------------------------------------------

	/**
	 * Get Month Name
	 *
	 * Generates a textual month name based on the numeric
	 * month provided.
	 *
	 * @access	public
	 * @param	integer	the month
	 * @return	string
	 */
	function get_month_name($month) {
		if ($this->month_type == 'short') {
			$month_names = array (
				'01' => 'cal_jan',
				'02' => 'cal_feb',
				'03' => 'cal_mar',
				'04' => 'cal_apr',
				'05' => 'cal_may',
				'06' => 'cal_jun',
				'07' => 'cal_jul',
				'08' => 'cal_aug',
				'09' => 'cal_sep',
				'10' => 'cal_oct',
				'11' => 'cal_nov',
				'12' => 'cal_dec'
			);
		} else {
			$month_names = array (
				'01' => 'cal_january',
				'02' => 'cal_february',
				'03' => 'cal_march',
				'04' => 'cal_april',
				'05' => 'cal_mayl',
				'06' => 'cal_june',
				'07' => 'cal_july',
				'08' => 'cal_august',
				'09' => 'cal_september',
				'10' => 'cal_october',
				'11' => 'cal_november',
				'12' => 'cal_december'
			);
		}

		$month = $month_names[$month];

		if ($this->CI->lang->line($month) === FALSE) {
			return ucfirst(str_replace('cal_', '', $month));
		}

		return $this->CI->lang->line($month);
	}

	// --------------------------------------------------------------------

	/**
	 * Get Day Names
	 *
	 * Returns an array of day names (Sunday, Monday, etc.) based
	 * on the type.  Options: long, short, abrev
	 *
	 * @access	public
	 * @param	string
	 * @return	array
	 */
	function get_day_names($day_type = '') {
		if ($day_type != '')
			$this->day_type = $day_type;

		if ($this->day_type == 'long') {
			$day_names = array (
				'sunday',
				'monday',
				'tuesday',
				'wednesday',
				'thursday',
				'friday',
				'saturday'
			);
		}
		elseif ($this->day_type == 'short') {
			$day_names = array (
				'sun',
				'mon',
				'tue',
				'wed',
				'thu',
				'fri',
				'sat'
			);
		} else {
			$day_names = array (
				'su',
				'mo',
				'tu',
				'we',
				'th',
				'fr',
				'sa'
			);
		}

		$days = array ();
		foreach ($day_names as $val) {
			$days[] = ($this->CI->lang->line('cal_' . $val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_' . $val);
		}
		return $days;
	}

	// --------------------------------------------------------------------

	/**
	 * Adjust Date
	 *
	 * This function makes sure that we have a valid month/year.
	 * For example, if you submit 13 as the month, the year will
	 * increment and the month will become January.
	 *
	 * @access	public
	 * @param	integer	the month
	 * @param	integer	the year
	 * @return	array
	 */
	function adjust_date($month, $year) {
		$date = array ();

		$date['month'] = $month;
		$date['year'] = $year;

		while ($date['month'] > 12) {
			$date['month'] -= 12;
			$date['year']++;
		}

		while ($date['month'] <= 0) {
			$date['month'] += 12;
			$date['year']--;
		}

		if (strlen($date['month']) == 1) {
			$date['month'] = '0' . $date['month'];
		}

		return $date;
	}

	// --------------------------------------------------------------------

	/**
	 * Total days in a given month
	 *
	 * @access	public
	 * @param	integer	the month
	 * @param	integer	the year
	 * @return	integer
	 */
	function get_total_days($month, $year) {
		$days_in_month = array (
			31,
			28,
			31,
			30,
			31,
			30,
			31,
			31,
			30,
			31,
			30,
			31
		);

		if ($month < 1 OR $month > 12) {
			return 0;
		}

		// Is the year a leap year?
		if ($month == 2) {
			if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0)) {
				return 29;
			}
		}

		return $days_in_month[$month -1];
	}

	// --------------------------------------------------------------------

	/**
	 * Set Default Template Data
	 *
	 * This is used in the event that the user has not created their own template
	 *
	 * @access	public
	 * @return array
	 */
	function default_template() {
		return array (
			'table_open' => '<table border="0" cellpadding="4" cellspacing="0">',
			'heading_row_start' => '<tr>',
			'heading_previous_cell' => '<th><a href="{previous_url}">&lt;&lt;</a></th>',
			'heading_title_cell' => '<th colspan="{colspan}">{heading}</th>',
			'heading_next_cell' => '<th><a href="{next_url}">&gt;&gt;</a></th>',
			'heading_row_end' => '</tr>',
			'week_row_start' => '<tr>',
			'week_day_cell' => '<td>{week_day}</td>',
			'week_row_end' => '</tr>',
			'cal_row_start' => '<tr>',
			'cal_cell_start' => '<td>',
			'cal_cell_start_today' => '<td>',
			'cal_cell_content' => '<a href="{content}">{day}</a>',
			'cal_cell_content_today' => '<a href="{content}"><strong>{day}</strong></a>',
			'cal_cell_no_content' => '{day}',
			'cal_cell_no_content_today' => '<strong>{day}</strong>',
			'cal_cell_blank' => '&nbsp;',
			'cal_cell_end' => '</td>',
			'cal_cell_end_today' => '</td>',
			'cal_row_end' => '</tr>',
			'table_close' => '</table>'
		);
	}

	// --------------------------------------------------------------------

	/**
	 * Parse Template
	 *
	 * Harvests the data within the template {pseudo-variables}
	 * used to display the calendar
	 *
	 * @access	public
	 * @return	void
	 */
	function parse_template() {
		$this->temp = $this->default_template();

		if ($this->template == '') {
			return;
		}

		$today = array (
			'cal_cell_start_today',
			'cal_cell_content_today',
			'cal_cell_no_content_today',
			'cal_cell_end_today'
		);

		foreach (array (
				'table_open',
				'table_close',
				'heading_row_start',
				'heading_previous_cell',
				'heading_title_cell',
				'heading_next_cell',
				'heading_row_end',
				'week_row_start',
				'week_row_end',
				'cal_row_start',
				'cal_cell_start',
				'cal_cell_content',
				'cal_cell_no_content',
				'cal_cell_blank',
				'cal_cell_end',
				'cal_row_end',
				'cal_cell_start_today',
				'cal_cell_content_today',
				'cal_cell_no_content_today',
				'cal_cell_end_today'
			) as $val) {
			if (preg_match("/\{" . $val . "\}(.*?)\{\/" . $val . "\}/si", $this->template, $match)) {
				$this->temp[$val] = $match['1'];
			} else {
				if (in_array($val, $today, TRUE)) {
					$this->temp[$val] = $this->temp[str_replace('_today', '', $val)];
				}
			}
		}
	}

}

// END CI_Calendar class

/* End of file Calendar.php */
/* Location: ./system/libraries/Calendar.php */